package edu.hawaii.duedates;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.junit.Test;

/**
 * TestDuesDates is a unit test for the DueDates class that checks for valid user input.
 * 
 * @author Team Purple John Ancheta Daniel Arakaki Mari-Lee Flestado
 * 
 * @version 1.1, October 14, 2008
 */
public class TestDueDates {
  
  /** Instance variable for -uhm option.*/
  public static final String uhmoption = "uhm";

  /** Instance variable for user id, instantiated to take in command argument. */
  //private static final String id = System.getProperties().getProperty("uhm.id");
  private static final String id = System.getenv("DUEDATES_TESTUSER2_ID");

  /** Instance variable for user last name, instantiated to take in command argument. */
  //private static final String lastName = System.getProperties().getProperty("uhm.lastname");
  private static final String lastName = System.getenv("DUEDATES_TESTUSER2_LASTNAME");
  
  //private static Pair bookInformation;
  
  private static List<Pair> bookList = new ArrayList<Pair>();

  /**
   * This method will check if uhm is true.
   */
  @Test
  public void testIsUhmOptionTrue() {
    DueDates dueDate = new DueDates();
    assertTrue("This should be true", dueDate.isUhmOption("-uhm"));
  }

  /**
   * This method will check if uhm is false.
   */
  @Test
  public void testIsUhmOptionFalse() {
    DueDates dueDate = new DueDates();
    assertFalse("This should be false", dueDate.isUhmOption(null));
  }

  /**
   * Tests for valid ID and last name with UH library.
   */
  @Test
  public void testGetUhValidEntry() {
    DueDates dueDates = new DueDates();
    try {
      dueDates.getUhmInfo(id, lastName, bookList);
    }
    catch (Exception e) {
      e.printStackTrace();
      fail("Unexpected exception thrown, problem with getUhmInfo.");
    }
  }

  /**
   * Tests for valid ID and invalid last name for UH library.
   * 
   * @throws Exception An exception is thrown should a user not enter a last name.
   */
  @Test(expected = Exception.class)
  public void testUhGetValidId() throws Exception {
    DueDates dueDate = new DueDates();
    String aLastName = null;
    
    dueDate.getUhmInfo(id, aLastName, bookList);
    fail("Should never reach here...");
    
  }

  /**
   * Tests for invalid ID and valid last name for UH library.
   * 
   * @throws Exception An exception is thrown should a user not enter an ID.
   */
  @Test(expected = Exception.class)
  public void testUhGetValidLastName() throws Exception {
    DueDates dueDate = new DueDates();
    String anId = null;
    dueDate.getUhmInfo(anId, lastName, bookList);
    fail("Should never reach here...");
  }

  /**
   * Tests for invalid ID and last name for UH library.
   * 
   * @throws Exception An exception is thrown should a user not enter an ID or last name.
   */
  
  @Test(expected = Exception.class)
  public void testUhGetInvalidEntry() throws Exception {
    DueDates dueDate = new DueDates();
    String id = null;
    String lastName = null;

    dueDate.getUhmInfo(id, lastName, bookList);
  }

  /**
   * Testing the DueDate.getSiteInfo with -uhm option.
   */
  @Test
  public void practiceApacheCommonCliUsageWithVerbose() {
    CommandLineParser parser = new PosixParser();
    Options options = new Options();
    options.addOption("v", "verbose", false, "Shows the Error exception stack trace.");
    try {
      String[] args = {"-verbose"};
      CommandLine cmd = parser.parse(options, args);
      assertTrue("long verbose option is on", cmd.hasOption("verbose"));
      assertTrue("short verbose option is on", cmd.hasOption("v"));
      assertFalse("is not an option", cmd.hasOption("notoption"));
    }
    catch (ParseException e) {
      e.printStackTrace();
      fail("Should never get here.");
    }
  }
  /**
   * Practice using Apache Common Cli command line parser with -uhm.
   */
  @Test
  public void practiceApacheCommonCliUsageWithUhmOptions() {
    CommandLineParser parser = new PosixParser();
    Options options = new Options();
    Option optionUhm = new Option(uhmoption, true, 
                                  "Site options for University of Hawaii at Manoa library" +
                                  "where <id> is the UH id number in 1234-5678 or 12345678 format" +
                                  "and <lastname> is the last name of the user");
    optionUhm.setArgs(2);
    //optionUhm.setRequired(true);
    options.addOption(optionUhm);
    try {
      String[] args = new String[]{"-uhm", "8765-4321", "mylastname"};
      CommandLine cmd = parser.parse(options, args);
      assertTrue("-uhm option is on", cmd.hasOption(uhmoption));
      String[] optionsUhm = cmd.getOptionValues(uhmoption);
      //in getSiteInfo, need to check if has correct number of option args
      assertEquals("should have two args", 2, optionsUhm.length);
      assertEquals("check id", "8765-4321", optionsUhm[0]);
      assertEquals("check lastname", "mylastname", optionsUhm[1]);
    }
    catch (ParseException e) {
      e.printStackTrace();
      fail("Should never get here.");
    }
  }
  /**
   * Practice using Apache Common Cli command line parser with multiple -uhm.
   */
  @Test
  public void practiceApacheCommonCliUsageWithMultipleUhmOptions() {
    CommandLineParser parser = new GnuParser();
    Options options = new Options();
    Option optionUhm = new Option(uhmoption, false, 
                                  "Site options for University of Hawaii at Manoa library" +
                                  "where <id> is the UH id number in 1234-5678 or 12345678 format" +
                                  "and <lastname> is the last name of the user");
    Option optionUhm2 = new Option("uhm2", false, 
        "Site options for University of Hawaii at Manoa library" +
        "where <id> is the UH id number in 1234-5678 or 12345678 format" +
        "and <lastname> is the last name of the user");
    optionUhm.setArgs(2);
    //optionUhm.setRequired(true);
    options.addOption(optionUhm);
    optionUhm2.setArgs(2);
    options.addOption(optionUhm2);
    //Bogus IDs for testing
    try {
      String[] args = new String[] {"-uhm", "8765-4321", "mylastname1",
                       "-uhm2", "8765-4322", "mylastname2",   
                      "-uhm2", "8765-4323", "mylastname3"};
      /*
      for (String s: args) {
        System.out.println(s);
      }
      */
      CommandLine cmd = parser.parse(options, args, true);
      String[] as = cmd.getArgs();
      for (String s : as) {
        System.out.println(s);
      }
      /*
      int total = 0;
      System.out.println(cmd.getOptions().length);
      for (Option option: cmd.getOptions()) {
        System.out.println(option.toString());
        if ("uhm".equals(option.getOpt())) {
          total++;
        } else if ("uhm2".equals(option.getOpt())) {
          total++;
        }
      }
      assertEquals("count total -uhm", 3, total);
      */
    }
    catch (ParseException e) {
      e.printStackTrace();
      fail("Should never get here.");
    }
  }
  
  /*@Test
  public void testGetUhmInfo() {
    DueDates dueDateTester = new DueDates();
    try {
      dueDateTester.getUhmInfo(id, lastName, bookList);
      //System.out.println(bookList.get(0));
      assertEquals("Testing for items in arraylist", "11-13-08 Book", bookList.get(0).toString());
    }
    catch (Exception e) {
      e.printStackTrace();
      fail("Unexpected exception thrown, problem with getUhmInfo.");
    }
  }*/
}
